﻿using ShiQuan.Logger;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ShiQuan.Sockets
{
    /// <summary>
    /// Socket 服务端
    /// </summary>
    public class SocketServer:IDisposable
    {
        public string Server { get; set; }

        public int Port { get; set; }

        public Socket Socket { get; set; }

        private Thread thread = null;

        private bool _RunState = false;
        /// <summary>
        /// 运行状态
        /// </summary>
        public bool RunState
        {
            get { return this._RunState; }
        }
        protected Dictionary<string, Socket> _SocketClients = new Dictionary<string, Socket>();
        /// <summary>
        /// 获取连接客户端
        /// </summary>
        public Dictionary<string, Socket> SocketClients
        {
            get { return this._SocketClients; }
        }

        protected ManualResetEvent _ManualReset = new ManualResetEvent(false);

        public SocketServer(string server,int port)
        {
            this.Server = server;
            this.Port = port;
        }
        /// <summary>
        /// 开始服务
        /// </summary>
        /// <returns></returns>
        public bool Start()
        {
            try
            {
                if(this.thread != null)
                {
                    this.thread.Abort();
                    this.thread = null;
                }
                //ip地址
                IPAddress ip = IPAddress.Parse(this.Server);
                IPEndPoint point = new IPEndPoint(ip, this.Port);
                //创建监听用的Socket
                this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                this.Socket.Bind(point);//socket监听哪个端口
                this.Socket.Listen(10);//同一个时间点过来10个客户端，排队
                this._RunState = true;
                this._SocketClients = new Dictionary<string, Socket>();

                //this.thread = new Thread(Accept);
                //this.thread.IsBackground = true;
                //this.thread.Start(this.Socket);
                this.Socket.BeginAccept(new AsyncCallback(Accept), this.Socket);
                Console.WriteLine("启用Socket服务器-"+this.Server+":"+this.Port+" 成功！");
                return RunState;
            }
            catch (Exception ex)
            {
                ThreadLogHelper.Error("启动Socket 服务器异常", ex);
                Console.WriteLine("启动Socket 服务器异常:" + ex.Message);
                return false;
            }
        }

        protected virtual void Accept(IAsyncResult result)
        {
            Socket server = result.AsyncState as Socket;
            try
            {
                Socket client = server.EndAccept(result);
                //处理下一个客户端连接
                server.BeginAccept(new AsyncCallback(Accept), server);

                string point = client.RemoteEndPoint.ToString();
                Console.WriteLine(point + "连接成功！");

                SocketReceive receive = new SocketReceive();
                receive.Id = Guid.NewGuid().ToString();
                receive.Socket = client;
                //接收客户端消息
                client.BeginReceive(receive.Buffer, 0, receive.Buffer.Length, SocketFlags.None, new AsyncCallback(Recieve), receive);
                //把客户端存入
                this._SocketClients.Add(receive.Id, client);
            }
            catch (Exception ex)
            {
                ThreadLogHelper.Error("接收Socket 客户端信息异常", ex);
                Console.WriteLine("接收Socket 客户端信息异常:" + ex.Message);
            }
        }

        protected virtual void Accept(object obj)
        {
            while(this._RunState)
            {
                try
                {
                    Socket socket = obj as Socket;
                    Console.WriteLine("监听客户端请求...");
                    //创建通信用的Socket
                    Socket client = socket.Accept();
                    string point = client.RemoteEndPoint.ToString();
                    Console.WriteLine(point + "连接成功！");

                    this._SocketClients.Add(point, client);
                    Thread thread = new Thread(this.Receive);
                    thread.IsBackground = true;
                    thread.Start(client);
                }
                catch (Exception ex)
                {
                    ThreadLogHelper.Error("接收Socket 客户端信息异常", ex);
                    Console.WriteLine("接收Socket 客户端信息异常:" + ex.Message);
                    break;
                }
            }
        }
        protected virtual void Recieve(IAsyncResult result)
        {
            SocketReceive client = result.AsyncState as SocketReceive;
            if (client == null)
            {
                return;
            }
            if(this._SocketClients.ContainsKey(client.Id) == false)
            {
                return;
            }
            try
            {
                int length = client.Socket.EndReceive(result);
                byte[] buffer = client.Buffer;

                SocketReceive receive = new SocketReceive();
                receive.Id = client.Id;
                receive.Socket = client.Socket;
                //接收消息
                client.Socket.BeginReceive(receive.Buffer, 0, receive.Buffer.Length, SocketFlags.None, new AsyncCallback(Recieve), receive);

                //byte[] receive = clientPool[client].buffer;
                string words = Encoding.UTF8.GetString(buffer, 0, length);
                Console.WriteLine(client.Socket.RemoteEndPoint.ToString() + ":" + words);
                /*向客户端发送内容*/
                string msg = "你好！";
                byte[] send = Encoding.UTF8.GetBytes(msg);
                client.Socket.Send(send);
            }
            catch(Exception ex)
            {
                this._SocketClients.Remove(client.Id);
                //把客户端标记为关闭，并在clientPool中清除
                client.Socket.Disconnect(true);

                ThreadLogHelper.Error("解释Socket 客户端信息异常", ex);
                Console.WriteLine("解释Socket 客户端信息异常:" + ex.Message);
            }
        }
        protected virtual void Receive(object obj)
        {
            while(true)
            {
                try
                {
                    Socket client = obj as Socket;
                    //定义byte数组存放从客户端接收过来的数据
                    byte[] buffer = new byte[1024 * 1024];
                    int n = client.Receive(buffer);
                    string words = Encoding.UTF8.GetString(buffer, 0, n);
                    Console.WriteLine(client.RemoteEndPoint.ToString() + ":" + words);
                    /*向客户端发送内容*/
                    string msg = "你好！";
                    byte[] send = Encoding.UTF8.GetBytes(msg);
                    client.Send(send);
                }
                catch (Exception ex)
                {
                    ThreadLogHelper.Error("解释Socket 客户端信息异常", ex);
                    Console.WriteLine("解释Socket 客户端信息异常:" + ex.Message);
                }
            }
        }
        /// <summary>
        /// 关闭连接
        /// </summary>
        public void Close()
        {
            this._RunState = false;
            if (this.thread != null)
            {
                this.thread.Abort();
                this.thread = null;
            }
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            this.Close();
        }
    }
}
